package io.easyspring.common.generator.generator;

import com.baomidou.mybatisplus.generator.AutoGenerator;
import io.easyspring.common.generator.builder.FileOutParameterBuilder;
import io.easyspring.common.generator.config.*;
import io.easyspring.common.generator.support.FileOutParameter;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Generator {

    /** 生成文件的输出目录 */
    private static final String SOURCE_CODE_ROOT_DIR = "/Users/summer/workspace/gitee/easy-spring/easy-spring-basis";
    /** mysql 的 xml 文件输出路径 */
    private static final String TEST_CODE_ROOT_DIR = "/Users/summer/workspace/gitee/easy-spring/easy-spring-test/basis-test";

    /** 数据源连接地址 */
    private static final String DATA_SOURCE_CONFIG_URL = "jdbc:mysql://47.96.126.38:3306/risk_management?useUnicode=true&characterEncoding=utf-8";
    /** 驱动器 */
    private static final String DATA_SOURCE_CONFIG_DRIVER_NAME = "com.mysql.jdbc.Driver";
    /** 用户名 */
    private static final String DATA_SOURCE_CONFIG_USERNAME = "root";
    /** 密码 */
    private static final String DATA_SOURCE_CONFIG_PASSWORD = "YinbaOWang";

    public void generator(String[] tablePrefixArr, String[] includeTableArr,
                          String serverPath, String modelName, String basePackagePath,
                          String parentPackageName) {
        // 循环表数据
        for (String includeTableInner : includeTableArr) {
            String tablePrefix = null;
            // 循环表前缀
            for (String tablePrefixInner : tablePrefixArr) {
                int indexOf = includeTableInner.indexOf(tablePrefixInner);
                if (indexOf == 0) {
                    tablePrefix = tablePrefixInner;
                }
            }

            if (!org.springframework.util.StringUtils.isEmpty(tablePrefix)) {
                AutoGenerator autoGenerator = getAutoGenerator(tablePrefix, includeTableInner,
                        serverPath, modelName, basePackagePath, parentPackageName);
                autoGenerator.execute();
            }
        }
    }

    /**
     * 执行生成
     * <p>
     * Author summer
     * DateTime 2018-12-13 14:48
     * Version V1.0.0-RELEASE
     */
    private AutoGenerator getAutoGenerator(String tablePrefix, String includeTable,
                                           String serverPath, String modelName, String basePackagePath,
                                           String parentPackageName) {
        // 创建生成器对象
        AutoGenerator autoGenerator = new AutoGenerator();

        // 全局配置
        autoGenerator.setGlobalConfig(GeneratorGlobalConfig.globalConfig(""));
        // 数据源配置
        autoGenerator.setDataSource(GeneratorDataSourceConfig.dataSourceConfig(DATA_SOURCE_CONFIG_URL,
                DATA_SOURCE_CONFIG_DRIVER_NAME, DATA_SOURCE_CONFIG_USERNAME, DATA_SOURCE_CONFIG_PASSWORD));
        // 策略配置
        autoGenerator.setStrategy(GeneratorStrategyConfig.strategyConfig(new String[]{tablePrefix},
                new String[]{includeTable}));

        // 包名配置
        autoGenerator.setPackageInfo(GeneratorPackageConfig.generatePackageConfig(parentPackageName, modelName));
        // 模板配置
        autoGenerator.setTemplate(GeneratorTemplateConfig.templateConfig());
        // 注入 injectionConfig 配置
        List<FileOutParameter> fileOutParameterList = FileOutParameterBuilder
                .buildOutParmeterList(getGeneratorOutputDirConfig(serverPath, modelName, basePackagePath));
        Map<String, Object> parameterMap = getParameterMap(serverPath, parentPackageName, modelName, tablePrefix, includeTable);

        autoGenerator.setCfg(GeneratorInjectionConfig.injectionConfig(parameterMap, fileOutParameterList));

        return autoGenerator;
        // 执行生成
//        autoGenerator.execute();
    }

    /**
     * TODO
     *
     * @param parentPackageName 父级的包名
     * @param modelName 模块的名称
     * @param tablePrefix 表前缀
     * @param includeTable 要生成的表
     * @return java.util.Map<java.lang.String,java.lang.Object>
     * Author summer
     * Version V1.0.0-RELEASE
     * DateTime 2019-05-12 21:12
     */
    private Map<String, Object> getParameterMap(String serverPath, String parentPackageName, String modelName, String tablePrefix,
                                                String includeTable) {
        // 获取去除前缀的表名
        String tableNameWithoutPrefix = includeTable.replaceAll(tablePrefix + "_", "");

        // api 服务的名称
        String baseServerName = serverPath.substring(1, serverPath.length());
        String apiServerName = baseServerName + GeneratorOutputDirConfig.API_PROJECT_SUFFIX;

        // 实体的名称
        String entityName = io.easyspring.framework.common.utils.StringUtils.underlineToCamel(tableNameWithoutPrefix);
        // 实体的 class 名称
        String entityClassName = io.easyspring.framework.common.utils.StringUtils.toUpperCaseFirstOne(entityName);

        // 时间
        Date thisTime = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //格式化为日期/时间字符串
        String dateTime = sdf.format(thisTime);

        Map<String, Object> parameterMap = new HashMap<>();
        // parameterMap.put("version", "0.0.1-SNAPSHOT");
        parameterMap.put("dateTime", dateTime);

        parameterMap.put("apiServerName", apiServerName);

        parameterMap.put("parameter_model", entityName);
        parameterMap.put("parameter_mapper", entityName + "Mapper");
        parameterMap.put("parameter_service", entityName + "Service");

        parameterMap.put("package_client", parentPackageName + "." + modelName + ".client");
        parameterMap.put("entity_client", entityClassName + "Client");
        parameterMap.put("entity_service_test", entityClassName + "ServiceImplTest");
        parameterMap.put("entity_controller_test", entityClassName + "ControllerTest");

        parameterMap.put("path_entity", tableNameWithoutPrefix);

        return parameterMap;
    }

    private GeneratorOutputDirConfig getGeneratorOutputDirConfig(String serverPath, String modelName, String basePackagePath) {

        return new GeneratorOutputDirConfig(
                SOURCE_CODE_ROOT_DIR,
                TEST_CODE_ROOT_DIR,
                serverPath,
                modelName,
                basePackagePath);
    }
}
